package org.idea.qiyu.framework.gateway.starter.registry;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.idea.qiyu.framework.gateway.starter.registry.zookeeper.AbstractZookeeperClient;
import org.idea.qiyu.framework.gateway.starter.registry.zookeeper.CuratorZookeeperClient;
import org.idea.qiyu.framework.gateway.starter.GatewayProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author linhao
 * @Date created in 8:35 上午 2022/4/16
 */
@Component
public class ZookeeperRegistry implements ApplicationRegistry{

    private static AbstractZookeeperClient abstractZookeeperClient;
    private static String ROOT = "/gateway";

    @Resource
    private GatewayProperties gatewayProperties;
    @Resource
    private ApplicationContext applicationContext;

    private AbstractZookeeperClient getClient(){
        if(abstractZookeeperClient==null){
            abstractZookeeperClient = new CuratorZookeeperClient(gatewayProperties.getRegistryAddress());
        }
        return abstractZookeeperClient;
    }

    @Override
    public void registry(URL url) {
        String nodeAddress = ROOT+"/"+url.getAddress()+"_"+url.getPort();
        if(getClient().existNode(nodeAddress)){
            getClient().deleteNode(nodeAddress);
        }
        getClient().createTemporaryData(nodeAddress,url.buildURLStr());
    }

    @Override
    public List<URL> getRegistryInfo() {
        List<String> childUrlList = getClient().getChildrenData(ROOT);
        List<URL> urls = new ArrayList<>(childUrlList.size());
        childUrlList.forEach(item ->{
            String data = getClient().getNodeData(ROOT+"/"+item);
            URL url = URL.buildURL(data);
            urls.add(url);
        });
        return urls;
    }


    @Override
    public void unRegistry(URL url) {
        getClient().deleteNode(ROOT+"/"+url.getApplicationName());
    }

    @Override
    public void subscribeURL() {
        System.out.println("订阅zk节点数据");
        getClient().watchChildNodeData(ROOT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("节点发生了变化");
                applicationContext.publishEvent(new ApplicationChangeEvent(this,watchedEvent.getType().getIntValue()));
                subscribeURL();
            }
        });

    }
}
